package o2o.config.annotation;

import o2o.cache.user.UserInfoMemory;
import o2o.cache.user.UserOnlineImpl;
import o2o.config.exception.JyResultException;
import o2o.dao.PO.user.UserInfo;
import o2o.utils.CommonUtils;
import o2o.utils.resp.EResultCode;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

/**
 * Created with IntelliJ IDEA.
 *
 * @User: @Created by yangtk
 * @Date: @Date 2020/11/11 19:46
 * @Email: yangtongkuan@qq.com
 * @To change this template use File | Settings | File Templates.
 * @desc 自定义方法适配器
 */
public class CustomLoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {

    private static final String TOKEN_KEY = "token";

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        /**
         * 只有有@LoginUser此注解并且是参数类型是UserEntity类型才可以
         */
        return parameter.getParameterType().isAssignableFrom(UserInfo.class) && parameter.hasParameterAnnotation(LoginUser.class);
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        String token = (String) CommonUtils.getReqParamVal(TOKEN_KEY);
        if (StringUtils.isBlank(token)) {
            if (isRequired(methodParameter)) {
                throw new JyResultException(EResultCode.NOT_LOGIN);
            }
        }
        UserInfo userInfo = UserInfoMemory.getInstance().getUserInfo(UserOnlineImpl.getInstance().get(token));
        if (userInfo == null) {
            if (isRequired(methodParameter)) {
                throw new JyResultException(EResultCode.NOT_LOGIN);
            }
        }
        return userInfo;
    }

    private boolean isRequired(MethodParameter methodParameter) {
        LoginUser loginUser = methodParameter.getParameterAnnotation(LoginUser.class);
        return loginUser == null ? false : loginUser.required();
    }
}
